/*
 * Copyright 2008 Johnny Jian
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.getris.game.score

import org.junit.AfterClass
import static org.junit.Assert.*
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test

class HighScoreManagerTest {

	static testDir = new File('test-files')

	def highScore

	@BeforeClass static void createTestDir() {
		testDir.mkdir()
	}

	@AfterClass static void removeTestDir() {
		testDir.delete()
	}

	@Before void setUp() {
		highScore = new HighScoreManager(top: 5)
		highScore.list << new ScoreItem(name: 'bbb', score: 100)
		highScore.list << new ScoreItem(name: 'aaa', score: 100)
		highScore.list << new ScoreItem(name: 'ccc', score: 200)
		highScore.list << new ScoreItem(name: 'aaa', score: 300)
		highScore.list << new ScoreItem(name: 'aaa', score: 200)
	}

	@Test void testConstructor() {
		final expected = [['aaa', 300], ['aaa', 200], ['ccc', 200], ['aaa', 100], ['bbb', 100]]
		highScore.list.eachWithIndex { item, i ->
			assertEquals expected[i][0], item.name
			assertEquals expected[i][1], item.score
		}
	}

	@Test void testIsTopScore() {
		assertTrue highScore.isTopScore(200)
		assertTrue highScore.isTopScore(300)
		assertTrue highScore.isTopScore(400)
		assertFalse highScore.isTopScore(100)
		assertFalse highScore.isTopScore(99)

		highScore.list.clear()
		assertTrue highScore.isTopScore(99)

		highScore.list << new ScoreItem(name: 'bbb', score: 100)
		assertTrue highScore.isTopScore(99)

		assertFalse highScore.isTopScore(0)
	}

	@Test void testIterator() {
		final expected = [['aaa', 300], ['aaa', 200], ['ccc', 200], ['aaa', 100], ['bbb', 100]]
		highScore.eachWithIndex { item, i ->
			assertEquals expected[i][0], item.name
			assertEquals expected[i][1], item.score
		}
	}

	@Test void testLeftShift() {
		final expected = [['ddd', 400], ['aaa', 300], ['aaa', 200], ['ccc', 200], ['aaa', 100]]
		highScore << ['ddd', 400]
		assertEquals 5, highScore.list.size()
		highScore.eachWithIndex { item, i ->
			assertEquals expected[i][0], item.name
			assertEquals expected[i][1], item.score
		}
	}

	@Test void testAddScore() {
		final expected = [['aaa', 300], ['aaa', 200], ['ccc', 200], ['ddd', 200], ['aaa', 100]]
		highScore.addScore(['ddd', 200])
		assertEquals 5, highScore.list.size()
		highScore.eachWithIndex { item, i ->
			assertEquals expected[i][0], item.name
			assertEquals expected[i][1], item.score
		}

		def old =  highScore.list.clone()
		highScore.addScore(['eee', 100])
		assertEquals old, highScore.list

		highScore.list.clear()
		highScore.addScore(['fff', 100])
		highScore.addScore(['ggg', 200])
		assertEquals 2, highScore.list.size()
		assertEquals 'ggg', highScore.list.first().name
		assertEquals 200, highScore.list.first().score
		assertEquals 'fff', highScore.list.last().name
		assertEquals 100, highScore.list.last().score
	}

	@Test void testSaveTo() {
		final expected = [['aaa', 300], ['aaa', 200], ['ccc', 200], ['aaa', 100], ['bbb', 100]]
		def file = new File(testDir, 'highscores.xml')

		highScore.saveTo file

		def highscores = new XmlSlurper().parse(file)
		highscores.item.eachWithIndex { item, i ->
			assertEquals expected[i][0], item.name.text()
			assertEquals expected[i][1], item.score.toInteger()
		}
		file.delete()
	}

	@Test void testLoadFrom() {
		final expected = [['aa', 30], ['aa', 20], ['cc', 20], ['aa', 10], ['bb', 10]]
		def file = new File(testDir, 'highscores.xml')
		file.write """
			<highscores>
			  <item>
				<name>aa</name>
				<score>30</score>
			  </item>
			  <item>
				<name>aa</name>
				<score>20</score>
			  </item>
			  <item>
				<name>cc</name>
				<score>20</score>
			  </item>
			  <item>
				<name>aa</name>
				<score>10</score>
			  </item>
			  <item>
				<name>bb</name>
				<score>10</score>
			  </item>
			</highscores>
		"""

		highScore.loadFrom file

		highScore.eachWithIndex { item, i ->
			assertEquals expected[i][0], item.name
			assertEquals expected[i][1], item.score
		}
		file.delete()
	}

	@Test void testReset() {
		assertFalse highScore.list.empty
		highScore.reset()
		assertTrue highScore.list.empty
	}

}
